#pragma once

#include <string>
#include <functional>
#include <future>

// SyraLink namespace
namespace sl {
class PreMainInitializer {
  public:
    PreMainInitializer();
    ~PreMainInitializer();
};

using byte = uint8_t;

void        print(const std::vector<byte>& data);
std::string hex_dump(const std::vector<byte>& data);

template <typename F, typename... Args>
requires std::invocable<F, Args...>
class Defer {
  public:
    Defer(F&& f, Args&&... args):
        _f(std::bind(std::forward<F>(f), std::forward<Args>(args)...)) { };
    ~Defer()
    {
        if(_f) {
            _f();
        }
    }

  private:
    std::function<void()> _f;
};

#define DEFER_CONCAT_IMPL(a, b) a##b
#define DEFER_CONCAT(a, b)      DEFER_CONCAT_IMPL(a, b)
#define defer(func, ...) \
    Defer DEFER_CONCAT(_defer_, __LINE__)(func, ##__VA_ARGS__)

#define ERR_LINE (-__LINE__)

class NonCopyable {
  protected:
    NonCopyable()          = default;
    virtual ~NonCopyable() = default;

    NonCopyable(const NonCopyable&)            = delete; // 禁止拷贝构造
    NonCopyable& operator=(const NonCopyable&) = delete; // 禁止拷贝赋值

    // NonCopyable(NonCopyable&&) = delete;
    // NonCopyable& operator=(NonCopyable&&) = delete;
};

struct DateHeader {
    uint32_t size;
    uint32_t crc;
};

} // namespace sl

/**
 * 网络连接层？ -- 实际socket读写
 *
 * 通道层 -- 通道连接池 -- 维护多个通道（Tunnel）负责通道
 * 建立-加密-解密-传输-心跳-容错 连接池分组？ - 对应不同的节点
 *
 * 会话 -- 维护一个端到端连接
 *
 */